package com.krtech.wecard.module.pub.controller;

import cn.hutool.core.codec.Base32;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.krtech.wecard.framework.exception.BusinessException;
import com.krtech.wecard.framework.utils.LoginUtil;
import com.krtech.wecard.module.oauth2.WecardOAuth2Enums;
import com.krtech.wecard.module.pub.dto.ApplicationEnums;
import com.krtech.wecard.module.pub.entity.ApplicationManagement;
import com.krtech.wecard.module.pub.service.ApplicationManagementService;
import com.krtech.wecard.module.sys.entity.StatisticalMain;
import com.krtech.wecard.module.sys.entity.SysDept;
import com.krtech.wecard.module.sys.entity.SysKeyValue;
import com.krtech.wecard.module.sys.entity.SysUser;
import com.krtech.wecard.module.sys.enums.SysEnums;
import com.krtech.wecard.module.sys.mapper.StatisticalMainMapper;
import com.krtech.wecard.module.sys.service.StatisticalMainService;
import com.krtech.wecard.module.sys.service.SysKeyValueService;
import com.krtech.wecard.module.sys.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.security.KeyPair;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 自建应用管理模块
 */
@RestController
@RequestMapping("/pub/application")
@Api(value = "应用管理",tags = "应用管理")
public class ApplicationManagementController {

    @Autowired
    private ApplicationManagementService applicationManagementService;

    @Autowired
    private SysKeyValueService keyValueService;

    @Autowired
    private StatisticalMainMapper statisticalMainMapper;

    @Autowired
    private SysUserService sysUserService;

    /**
     * 增
     */
    @PutMapping("/add")
    @ApiOperation(value = "新增")
    public ApplicationManagement add(@RequestBody ApplicationManagement applicationManagement){
        SysUser userInfo = LoginUtil.getUserInfo();
        if (StrUtil.isEmpty(applicationManagement.getName())){
            throw new BusinessException("必填参数name不能不为空");
        }
        applicationManagement.setCode(applicationManagement.getName());
        //查询名字和code不能重复
        int nameCount = applicationManagementService.count(new QueryWrapper<ApplicationManagement>()
                .eq(ApplicationManagement.COL_NAME, applicationManagement.getName()));
        if (nameCount > 0){
            throw new BusinessException("应用名称不能重复");
        }

        int codeCount = applicationManagementService.count(new QueryWrapper<ApplicationManagement>()
                .eq(ApplicationManagement.COL_NAME, applicationManagement.getCode()));
        if (codeCount > 0){
            throw new BusinessException("应用code不能重复");
        }

        // 小程序上限只能有几个
        if (applicationManagement.getType().equals(ApplicationEnums.APPLICATION_TYPE_SMALL_PROGRAM)){
            SysKeyValue applicationMax = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                    .eq(SysKeyValue.COL_SYS_KEY, ApplicationEnums.APPLICATION_MAX));
            int smallProgramCount = applicationManagementService.count(new QueryWrapper<ApplicationManagement>()
                    .eq(ApplicationManagement.COL_TYPE, ApplicationEnums.APPLICATION_TYPE_SMALL_PROGRAM));

            if (smallProgramCount >= Integer.parseInt(applicationMax.getSysValue())){
                throw new BusinessException("小程序配置达到上限，请联系管理员");
            }
        }

        applicationManagement.setCreatedBy(userInfo.getUserId().toString());
        applicationManagement.setCreatedTime(new Date());
        applicationManagement.setStatus(0);

        //生成appKey和secret
        //todo 生成的一毛一样
        String appKey = IdUtil.simpleUUID();
        String encode = Base32.encode(appKey);
        String secret = encode.substring(0, 32);

        applicationManagement.setAppKey(appKey);
        applicationManagement.setAppSecret(secret);

        if (StrUtil.isNotEmpty(applicationManagement.getPicUrl())){
            SysKeyValue domain = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                    .eq(SysKeyValue.COL_SYS_NAME, WecardOAuth2Enums.DOMAIN));

            if (!applicationManagement.getPicUrl().contains(domain.getSysValue())){
                applicationManagement.setPicUrl(domain.getSysValue() + applicationManagement.getPicUrl());
            }
        }


        applicationManagementService.save(applicationManagement);
        return applicationManagement;
    }

    /**
     * 改
     * @param applicationManagement
     * @return
     */
    @PutMapping("/update")
    @ApiOperation(value = "更新")
    public ApplicationManagement update(@RequestBody ApplicationManagement applicationManagement){
        if (StrUtil.isEmpty(applicationManagement.getCode())){
            throw new BusinessException("必填参数code不能不为空");
        }
        if (StrUtil.isNotEmpty(applicationManagement.getPicUrl())){
            SysKeyValue domain = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                    .eq(SysKeyValue.COL_SYS_NAME, WecardOAuth2Enums.DOMAIN));

            if (!applicationManagement.getPicUrl().contains(domain.getSysValue())){
                applicationManagement.setPicUrl(domain.getSysValue() + applicationManagement.getPicUrl());
            }
        }

        applicationManagementService.updateById(applicationManagement);
        return applicationManagement;
    }

    /**
     * 删除
     */
    @DeleteMapping("/delete")
    @ApiOperation(value = "删除")
    public Boolean delete( Integer id){
        if (id == null){
            throw new BusinessException("必填参数id不能不为空");
        }
        applicationManagementService.removeById(id);
        return true;
    }

    /**
     * getById
     * @param id
     * @return
     */
    @GetMapping("/getById")
    @ApiOperation(value = "getById")
    public ApplicationManagement getById(Integer id){
        if (id == null){
            throw new BusinessException("必填参数id不能不为空");
        }

        return applicationManagementService.getById(id);
    }

    @GetMapping("/page")
    @ApiOperation(value = "分页查询")
    public Page<ApplicationManagement> page(Page<ApplicationManagement> page,String keyword){
        QueryWrapper<ApplicationManagement> wrapper = new QueryWrapper<>();
        wrapper.eq(ApplicationManagement.COL_DEL_FLAG,0);
        if (StrUtil.isNotEmpty(keyword)){
            wrapper.like(ApplicationManagement.COL_NAME,keyword)
            .or()
            .like(ApplicationManagement.COL_CODE,keyword);
        }
        Page<ApplicationManagement> managementPage = applicationManagementService.page(page, wrapper);
        return managementPage;
    }

    @GetMapping("/list")
    @ApiOperation(value = "list")
    public List<ApplicationManagement> list(String keyword){
        QueryWrapper<ApplicationManagement> wrapper = new QueryWrapper<>();
        wrapper.eq(ApplicationManagement.COL_DEL_FLAG,0);
        wrapper.eq(ApplicationManagement.COL_STATUS, ApplicationEnums.APPLICATION_OPEN);
        if (StrUtil.isNotEmpty(keyword)){
            wrapper.like(ApplicationManagement.COL_NAME,keyword)
                    .or()
                    .like(ApplicationManagement.COL_CODE,keyword);
        }
        List<ApplicationManagement> list = applicationManagementService.list(wrapper);
        return list;
    }

    @GetMapping("/commonApplication")
    @ApiOperation(value = "常用应用")
    public List<ApplicationManagement> commonApplication(){
        SysUser userInfo = LoginUtil.getUserInfo();

        SysKeyValue keyValue = keyValueService.getOne(new QueryWrapper<SysKeyValue>()
                .eq(SysKeyValue.COL_SYS_NAME, SysEnums.COMMON_APPLICATION));
        if (keyValue == null){
            throw new BusinessException("微卡常用应用数量未配置，请联系管理员配置");
        }


        List<ApplicationManagement> list = statisticalMainMapper.CommonApplication(userInfo.getUserCode());

        // 筛选出是当前人配置了的应用
        List<ApplicationManagement> haveApplicationList = sysUserService.getApplicationListByCurrentUserIdentfify();

        ArrayList<ApplicationManagement> currentUserIdentityHaveApplication = new ArrayList<>();
        for (ApplicationManagement oneApplication:list){
            for (ApplicationManagement haveApplication:haveApplicationList){
                if (oneApplication.getId().equals(haveApplication.getId())){
                    currentUserIdentityHaveApplication.add(oneApplication);
                }
            }
        }

        //判断是否有权限,先将有权限的筛选出来，再选七个
        ArrayList<ApplicationManagement> filterList = new ArrayList<>();
        for (ApplicationManagement oneApplication:currentUserIdentityHaveApplication){
            // 判断当前用户是否可用这个应用，应用包含的部门以及人是否有当前用户
            if (StrUtil.isEmpty(oneApplication.getAllowDeptList()) && StrUtil.isEmpty(oneApplication.getAllowUserList())){
                continue;
            }

            if (StrUtil.isNotEmpty(oneApplication.getAllowDeptList())){
                List<SysDept> deptList = JSONUtil.toList(oneApplication.getAllowDeptList(), SysDept.class);
                if (deptList.size() > 0){
                    List<String> DeptCodeList = deptList.stream().map(SysDept::getCode).collect(Collectors.toList());
                    if (DeptCodeList != null && DeptCodeList.size() > 0){
                        List<String> deptCodeListAndSon = sysUserService.getDeptAndSonAsListByDeptCodeList(DeptCodeList);
                        if (deptCodeListAndSon.size() > 0 && deptCodeListAndSon.contains(userInfo.getDeptCode())){
                            filterList.add(oneApplication);
                            continue;
                        }
                    }

                }
            }

            if (StrUtil.isNotEmpty(oneApplication.getAllowUserList())){
                List<SysUser> sysUserList = JSONUtil.toList(oneApplication.getAllowUserList(), SysUser.class);
                if (sysUserList.size() > 0){
                    List<String> userCodeList = sysUserList.stream().map(SysUser::getUserCode).collect(Collectors.toList());
                    if (userCodeList.size() > 0 && userCodeList.contains(userInfo.getUserCode())){
                        filterList.add(oneApplication);
                        continue;
                    }
                }

            }
        }


        int number = Integer.parseInt(keyValue.getSysValue());

        List<ApplicationManagement> result = new ArrayList<>();

        if (filterList.size() > 0){
            for (int i =0;i<number && i<filterList.size();i++){
                result.add(filterList.get(i));
            }
        }



        return result;
    }


}
